package br.com.pd.messaging;

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import br.com.util.ConstantsConfiguration;
import br.com.util.PropertiesLoader;

public class RequestSender  extends Thread implements Subject {


	private int checkerPeriod;
	
	private int maxTrySends;
	
	private List<Listener> listeners;
	
	private Queue<MessageInfo> queueSend;
	
	public RequestSender(){
		this.queueSend = new ConcurrentLinkedQueue<MessageInfo>();
		this.listeners = new ArrayList<Listener>();
		this.checkerPeriod = Integer.parseInt(PropertiesLoader.getInstance().getPropertie(PropertiesLoader.MESSAGE_CHECKER_PERIOD));
		this.maxTrySends = Integer.parseInt(PropertiesLoader.getInstance().getPropertie(PropertiesLoader.MAX_TRY_SENDS));
	}
	

	public void send(String b, String location, int port) {
		queueSend.add(new MessageInfo(b, location, port));
	}

	
	private boolean sendSocket(String b, String location, int port ){
		Socket clientSocket = null;
		try {
			clientSocket = new Socket(location, port);
			PrintStream ps = new PrintStream(clientSocket
					.getOutputStream());
			ps.println(b);
			System.out.println("mensagem enviada " + b);
		} catch (Exception e) {
			return false;
		}finally{
			if (clientSocket != null) {
				try {
					clientSocket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return true;
	}
	
	
	
	@Override
	public void run(){
		while(true){
			if (this.queueSend != null && !this.queueSend.isEmpty()) {
					Iterator it = queueSend.iterator();
					while (it.hasNext()) {
						MessageInfo m = (MessageInfo) it.next();
						System.out.println("Debug: numberofSends : " + m.numberOfSends + " max  " + this.maxTrySends);
						if(this.sendSocket(m.clientSentence, m.getLocation(), m.getPort()) || m.getNumberOfSends() >= this.maxTrySends ){
							this.queueSend.remove(m);
							if (m.getNumberOfSends() >= this.maxTrySends ) {
								System.out.println("Debug: Numero de tentativas limite ultrapassada, mensagem descartada");	
							}
						}else {
							m.addNumberOfSends();
						}

					}
			}
			try {
				this.sleep(checkerPeriod);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	@Override
	public void addObserver(Listener o) {
		this.listeners.add(o);
	}

	@Override
	public void removeObserver(Listener o) {
		this.listeners.remove(o);
	}

	
	private class MessageInfo {

		private String clientSentence;
		private String location;
		private int port;
		private int numberOfSends;
		
		public MessageInfo(String clientSentence, String location, int port) {
			this.clientSentence = clientSentence;
			this.numberOfSends = 0;
			this.location = location;
			this.port = port;
		}
		
		public String getClientSentence() {
			return clientSentence;
		}

		public void addNumberOfSends(){
			this.numberOfSends++;
		}
		
		public void resetNumberOfSends(){
			this.numberOfSends = 0;
		}
		
		public int getNumberOfSends(){
			return this.numberOfSends;
		}

		public String getLocation() {
			return location;
		}

		public void setLocation(String location) {
			this.location = location;
		}

		public int getPort() {
			return port;
		}

		public void setPort(int port) {
			this.port = port;
		}
		
		
	}
	
	
}
